/*
 * Copyright 2009 BioTeam Inc
 * 
 * Licensed under License GNU LESSER GENERAL PUBLIC LICENSE version 3.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.gnu.org/copyleft/lesser.html
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package net.bioteam.appweb.gwt.apps.server.dataanalysis;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import net.bioteam.appweb.datatype.FixedValue;
import net.bioteam.appweb.datatype.Input;
import net.bioteam.appweb.datatype.Output;
import net.bioteam.appweb.datatype.ParameterMap;
import net.bioteam.appweb.datatype.ParameterMapBuilder;
import net.bioteam.appweb.datatype.SimpleDataType;
import net.bioteam.appweb.gwt.apps.clientandserver.ServerException;
import net.bioteam.appweb.gwt.apps.clientandserver.dataanalysis.DataAnalysisAction;
import net.bioteam.appweb.gwt.apps.clientandserver.dataanalysis.FormData;
import net.bioteam.appweb.gwt.apps.clientandserver.dataanalysis.TypeNode;
import net.bioteam.appweb.gwt.apps.server.MyRemoteServiceServlet;
import net.bioteam.appweb.model.Program;
import net.bioteam.appweb.model.ProgramBuilder;
import net.bioteam.appweb.submit.ProgramValueBean;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class DataAnalysisActionImpl extends MyRemoteServiceServlet implements DataAnalysisAction {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	public static final Log logger=LogFactory.getLog(DataAnalysisActionImpl.class);
	public Map<String, String> getRelatedServices() throws ServerException
	{
		String mobytype="NucleotideSequence";
		HttpServletRequest request=this.getThreadLocalRequest();
		AnalysisData data=(AnalysisData )request.getSession().getAttribute(AnalysisData.AnalysisSessionKey);

		mobytype=data.getMobytype();
		
		Map<String, String> ret=new HashMap<String, String>();
		
		List<String> types=ParameterMapBuilder.findTypeAndParentType(mobytype);
		
		Set<ParameterMap> maps=ParameterMapBuilder.findMapsByInputs(types);

		if (maps==null)
		{
			return ret;
		}
		for (ParameterMap map: maps)
		{
			ret.put(map.getFilekey(), map.getServiceDescription());
		}
		return ret;
	}

	public FormData getFormData(String serviceID) throws ServerException
	{
		HttpServletRequest request=this.getThreadLocalRequest();
		AnalysisData adata=(AnalysisData )request.getSession().getAttribute(AnalysisData.AnalysisSessionKey);
		String mobytype=adata.mobytype;
		adata.paramName=null;
		
		FormData data=new FormData();
		ParameterMap map=ParameterMapBuilder.filekeyMaps.get(serviceID);
		adata.setMap(map);
		try
		{
			Program p=ProgramBuilder.getProgram(map.getProgram());
			if (p==null)
			{
				throw new NullPointerException("program "+map.getProgram()+" does not exist anymore");
			}
			ProgramValueBean bean=new ProgramValueBean(p);
			List<String> required=new ArrayList<String>();
			List<String> omitted=new ArrayList<String>();
			List<String> hidden=new ArrayList<String>();
			for (Input input:map.getInputs())
			{
				if (adata.paramName==null)
				{
					if (ParameterMapBuilder.isParentType(input.getMobyTypeName(), mobytype))
					{
						omitted.add(input.getParamName());
						adata.paramName=input.getParamName();
					} else
					{
						required.add(input.getParamName());
					}
				} else
				{
					required.add(input.getParamName());
				}	
			}
			for (Output output:map.getOutputs())
			{
				if (output.getFixedValue()!=null)
				{
					hidden.add(output.getParamName());
					bean.setValue(output.getParamName(), output.getFixedValue());
				}
			}
			for (FixedValue fv: map.getFixedValues())
			{
				hidden.add(fv.getParamName());
				bean.setValue(fv.getParamName(), fv.getValue());
			}
			data.bean=bean;
			data.map=map;
			data.hidden=hidden;
			data.ommitted=omitted;
			data.required=required;
			return data;
		} catch (Exception e)
		{
			logger.warn("error when building form data", e);
			throw new ServerException(e.getMessage());
		}
		
		
	}
	
	public TypeNode[] getUsedType(String name) throws ServerException
	{
		SimpleDataType type=ParameterMapBuilder.findType(name);
		TypeNode[] nodes=new TypeNode[type.getChildren().size()];
		int count=0;
		for (SimpleDataType child: type.getChildren())
		{
			nodes[count]=simpleDataTypeToTypeNode(child);
			count++;
		}
		return nodes;
	}
	
	private TypeNode simpleDataTypeToTypeNode(SimpleDataType t)
	{
		TypeNode tn=new TypeNode();
		tn.name=t.getName();
		tn.description=t.getDescription();
		if (t.getChildren()!=null && !t.getChildren().isEmpty())
		{
			tn.nodes=new TypeNode[t.getChildren().size()];
			int count=0;
			for (SimpleDataType st: t.getChildren())
			{	
				tn.nodes[count]=simpleDataTypeToTypeNode(st);
				count++;
			}
		}
		return tn;
	}

}
